﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using static TorchSharp.torch;
using static TorchSharp.torch.nn;

namespace NgpSharp
{
    public class RayMachingLoader
    {
        [DllImport("RayMarching", EntryPoint = "near_far_from_aabb")]
        public static extern void near_far_from_aabb(IntPtr rays_o, IntPtr rays_d, IntPtr aabb, uint N, float min_near, IntPtr nears, IntPtr fars);

        [DllImport("RayMarching", EntryPoint = "march_rays_train")]
        public static extern void march_rays_train(IntPtr rays_o, IntPtr rays_d, IntPtr grid, float bound, float dt_gamma, uint max_steps, uint N, uint C, uint H, uint M,
            IntPtr nears, IntPtr fars, IntPtr xyzs, IntPtr dirs, IntPtr deltas, IntPtr rays, IntPtr counter, IntPtr noises);
        [DllImport("RayMarching", EntryPoint = "composite_rays_train_forward")]
        public static extern void composite_rays_train_forward(IntPtr sigmas, IntPtr rgbs, IntPtr deltas, IntPtr rays, uint M, uint N, float T_thresh, IntPtr weights_sum, IntPtr depth, IntPtr image);
        [DllImport("RayMarching", EntryPoint = "composite_rays_train_backward")]
        public static extern void composite_rays_train_backward(IntPtr grad_weights_sum, IntPtr grad_image, IntPtr sigmas, IntPtr rgbs, IntPtr deltas,
            IntPtr rays, IntPtr weights_sum, IntPtr image, uint M, uint N, float T_thresh, IntPtr grad_sigmas, IntPtr grad_rgbs);

        [DllImport("RayMarching", EntryPoint= "morton3D")]
        public static extern void morton3D(IntPtr coords, uint N, IntPtr indices);
        [DllImport("RayMarching", EntryPoint= "morton3D_invert")]
        public static extern void morton3D_invert(IntPtr indices, uint M, IntPtr coords);

        [DllImport("RayMarching", EntryPoint = "sph_from_ray")]
        public static extern void sph_from_ray(IntPtr rays_o, IntPtr rays_d, float radius, uint N, IntPtr coords);

        [DllImport("RayMarching", EntryPoint = "rays_coords")]
        public static extern void rays_coords(IntPtr rays_o, IntPtr rays_d, IntPtr aabb, uint num_steps, float min_near, uint N, [MarshalAs(UnmanagedType.I1)] bool perturb,
            IntPtr nears, IntPtr fars, IntPtr xyzs, IntPtr z_vals, IntPtr deltas);
    }
}
